﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SolutionFramework.Entities;
using AbstraX.Contracts;
using VisualStudioProvider;
using System.Threading;
using System.Diagnostics;
using AbstraX.AssemblyInterfaces;
using AbstraX.ServerInterfaces;
using System.Net;
using System.IO;
using AbstraX.Bindings.Interfaces;
using CodeGenerationPipeline;
using Microsoft.Practices.Unity;
using AbstraX;
using VisualStudioProvider.Templates;

namespace SolutionFramework.Web
{
    public class DomainHostApplication : IDomainHostApplication
    {
        private string imageEditorUrl;
        private string testSolutionPath;
        private Queue<string> statusMessageQueue;
        private IAssemblyProviderService assemblyProviderService;
        private Dictionary<string, IAbstraXProviderService> registeredServices;
        private IBindingsTreeCache bindingsTreeCache;
        private BindingsGenerator bindingsGenerator;
        private IEventsService eventsService;
        private Queue<BuildUIQueueEntry> buildUIQueue;
        public bool FinishBuildWithDefaults { get; set; }
        private IPipelineService pipelineService;

        public DomainHostApplication()
        {
            var path = new DirectoryInfo(HttpContext.Current.Request.PhysicalApplicationPath).Parent.FullName;

            testSolutionPath = Path.Combine(path, "SolutionFramework.sln");

            var file = new FileInfo(testSolutionPath);

            if (!file.Exists)
            {
                testSolutionPath = Path.Combine(path, "Web.sln");
            }

            file = new FileInfo(testSolutionPath);
            
            if (!file.Exists)
            {
                Debugger.Break();
            }

            statusMessageQueue = new Queue<string>();
        }

        public IBindingsTreeCache BindingsTreeCache
        {
            get 
            {
                if (bindingsTreeCache == null)
                {
                    bindingsTreeCache = new BindingsTreeCache();
                }

                return bindingsTreeCache;
            }
        }

        public string ImageEditorUrl
        {
            get
            {
                return imageEditorUrl;
            }
            set
            {
                imageEditorUrl = value;
            }
        }

        public string GetImageEditorUrl()
        {
            return imageEditorUrl;
        }

        public List<IVSSolution> Solutions
        {
            get 
            {
                var solution = new VSSolution(testSolutionPath);

                return new List<IVSSolution>() { solution };
            }
        }

        public void SetStatus(string status)
        {
            Monitor.Enter(statusMessageQueue);
            statusMessageQueue.Enqueue(status);
            Monitor.Exit(statusMessageQueue);
        }

        public List<string> LatestStatus
        {
            get 
            {
                List<string> status = new List<string>();

                Monitor.Enter(statusMessageQueue);

                while (statusMessageQueue.Count > 0)
                {
                    status.Add(statusMessageQueue.Dequeue());
                }

                Monitor.Exit(statusMessageQueue);

                return status;
            }
        }

        public IAssemblyProviderService AssemblyProviderService 
        {
            get 
            {
                return assemblyProviderService;
            }

            set
            {
                assemblyProviderService = value;
            }
        }

        public Dictionary<string, IAbstraXProviderService> RegisteredServices
        {
            get 
            {
                if (registeredServices == null)
                {
                    registeredServices = new Dictionary<string, IAbstraXProviderService>();
                }

                return registeredServices;
            }
        }

        public IBindingsGenerator BindingsGenerator
        {
            get 
            {
                if (bindingsGenerator == null)
                {
                    bindingsGenerator = new BindingsGenerator(this);
                }

                return bindingsGenerator;
            }
        }

        public IUnityContainer PipelineContainer
        {
            get 
            {
                return IoC.Container;
            }
        }

        public IEventsService EventsService
        {
            get
            {
                return eventsService;
            }
            set
            {
                eventsService = value;
            }
        }

        public void PostEventShowUI(string uiComponentURL, string parms, IBuildUIDaemon buildUIDaemon, TimeSpan waitTimeout)
        {
            this.BuildUIQueue.Enqueue(new BuildUIQueueEntry { BuildUIDaemon = buildUIDaemon, URL = uiComponentURL });

            this.EventsService.PostMessage(new EventMessage(Message.ShowUI, uiComponentURL, parms), buildUIDaemon, waitTimeout);
        }

        public void PostEventShowUI(string uiComponentURL, string parms)
        {
            this.EventsService.PostMessage(new EventMessage(Message.ShowUI, uiComponentURL, parms));
        }

        public void PostEventBuildMessage(string message)
        {
            this.EventsService.PostMessage(new EventMessage(Message.BuildMessage, message));
        }

        public void PostEventBuildComplete()
        {
            this.EventsService.PostMessage(new EventMessage(Message.BuildComplete));
        }

        public void PostEventError(string errorMessage)
        {
            this.EventsService.PostMessage(new EventMessage(Message.Error, errorMessage));
        }

        public void PostEventPercentComplete(float percentComplete)
        {
            this.EventsService.PostMessage(new EventMessage(Message.PercentComplete, percentComplete));
        }

        public void ClearQueue()
        {
            if (this.EventsService != null)
            {
                this.EventsService.ClearQueue();
            }
        }

        public void ClearWait(bool finishWithDefaults = false)
        {
            this.FinishBuildWithDefaults = finishWithDefaults;

            this.EventsService.ClearWait();
        }

        public Queue<BuildUIQueueEntry> BuildUIQueue
        {
            get 
            {
                if (buildUIQueue == null)
                {
                    buildUIQueue = new Queue<BuildUIQueueEntry>();
                }
                
                return buildUIQueue;
            }
        }

        public IPipelineService PipelineService
        {
            get 
            {
                if (pipelineService == null)
                {
                    pipelineService = new PipelineService(this);
                }

                return pipelineService;
            }
        }

        public Dictionary<string, ICodeTemplate> ProjectGroupTemplates
        {
            get 
            {
                return TemplateProvider.ProjectGroupTemplates;
            }
        }

        public Dictionary<string, ICodeTemplate> ProjectTemplates
        {
            get 
            {
                return TemplateProvider.ProjectTemplates;
            }
        }

        public Dictionary<string, ICodeTemplate> ItemTemplates
        {
            get
            {
                return TemplateProvider.ItemTemplates;
            }
        }


        public Dictionary<string, IBuildFilter> BuildFilters
        {
            get 
            {
                var filters = new Dictionary<string, IBuildFilter>();
                var testFilter = new TestBuildFilter();

                filters.Add(testFilter.Name, testFilter);

                return filters;
            }
        }
    }
}